#include "VulkanMeshs.h"
#include "WriteInMesh.h"
#include "Render/PreRender/PreRenderMesh.h"
#include "VulkanMesh.h"

void CVulkanMeshs::UpdateMeshs(const TVector<std::shared_ptr<CPreRenderMesh>>& AllMeshData)
{
    auto OldMeshs = Meshs;
    Meshs.Clear();

    TVector<TThreadSafeSharedPtr<CWriteInMesh>> NeedUpdateMeshs;
    for (auto &PreRenderMesh : AllMeshData)
    {
        auto WriteInMesh = PreRenderMesh->WriteInData;
        auto FindMesh = OldMeshs.Find(WriteInMesh);
        if (FindMesh)
        {
            Meshs.Add(WriteInMesh, *FindMesh);
            if(WriteInMesh->IsDirty())
            {
                NeedUpdateMeshs.Add(WriteInMesh);
            }
        }
        else
        {
            auto NewMesh = std::make_shared<CVulkanMesh>();
            Meshs.Add(WriteInMesh, NewMesh);
            NeedUpdateMeshs.Add(WriteInMesh);
        }
    }

    OldMeshs.Clear();

    for (auto &MeshData : NeedUpdateMeshs)
    {
        auto VulkanMesh = Meshs[MeshData];
        std::lock_guard<std::mutex> LockGuard(MeshData->Mutex);
        MeshData->bDirty = false;

        VulkanMesh->VertexCount=MeshData->Vertice.Num();
        
        //create buffer
        if (!VulkanMesh->VertexBuffer 
            || VulkanMesh->VertexBuffer->GetSize()!=VulkanMesh->VertexCount * sizeof(SVertex))
        {
            VulkanMesh->VertexBuffer=std::make_shared<CVulkanVertexBuffer>(VulkanMesh->VertexCount * sizeof(SVertex));
        }
       
        //写入顶点数据
        VulkanMesh->VertexBuffer->WriteData(MeshData->Vertice.Data(), VulkanMesh->VertexCount * sizeof(SVertex));

        VulkanMesh->IndexCount=MeshData->Indices.Num();

        if(VulkanMesh->IndexCount>0)
        {
            //create index buffer
            if (!VulkanMesh->IndexBuffer
                || VulkanMesh->IndexBuffer->GetSize()!=VulkanMesh->IndexCount * sizeof(uint32_t)
            )
            {
                VulkanMesh->IndexBuffer=std::make_shared<CVulkanIndexBuffer>(VulkanMesh->IndexCount * sizeof(uint32_t));   
            }

            //写入索引数据
            VulkanMesh->IndexBuffer->WriteData(MeshData->Indices.Data(), VulkanMesh->IndexCount * sizeof(uint32_t));
        }

    };

}

std::shared_ptr<CVulkanMesh> CVulkanMeshs::FindVulkanObj(TThreadSafeSharedPtr<CWriteInMesh> Mesh)
{
    return Meshs[Mesh];
}
